#include "acceptor.h"
#include "common.h"
#include "connecteh.h"
#include "event.h"
#include "reactor.h"
#include <errno.h>
#include <fcntl.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>

acceptor_t *create_acceptor(int listenfd, reactor_t *self)
{
	acceptor_t *acceptor;
	struct epoll_event ev;

	acceptor = (acceptor_t *)malloc(sizeof(acceptor_t));
	if (acceptor == NULL)
	{
		outputError(errno, "%s", "malloc acceptor_t");
	}
	acceptor->listenfd = listenfd;
	acceptor->handle_event = handle_event;

	ev.data.fd = listenfd;
	ev.events = EPOLLIN | EPOLLET | EPOLLRDHUP;
	// ev.events = EPOLLIN;

	if (epoll_ctl(self->core->epoll_fd, EPOLL_CTL_ADD, listenfd, &ev) != 0)
	{
		outputError(errno, "%s", "epoll_ctl");
	}

	return acceptor;
}

static void *handle_event(void *msg)
{
	event_handler_t *eh;
	int fd, connfd, flags;
	reactor_t *reactor = (reactor_t *)msg;

	fd = reactor->acceptor->listenfd;
	if ((connfd = accept(fd, NULL, NULL)) == -1)
	{
		outputError(errno, "%s", "accept");
	}

	flags = fcntl(connfd, F_GETFL);
	flags |= O_NONBLOCK;
	if (fcntl(connfd, F_SETFL, flags) == -1)
	{
		outputError(errno, "%s", "fcntl");
	}

	eh = create_connecteh(connfd, reactor);
	reactor->add_eh(reactor, eh);
}
